package org.example.day07;

/**
 * 第三章节3.1.13: 方法notify只唤醒一个线程
 *      唤醒的是最先wait的线程(类似队列)
 *      ★★不确定: notify唤醒线程后，在其释放锁时，被唤醒的wait线程好像比其他线程更易获得锁.
 */
public class MyThread11 {
    private Object lock = new Object();

    public void waitMethod() {
        try {
            synchronized (lock) {
                System.out.println("begin wait ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
                lock.wait(); //释放锁
                System.out.println("end wait ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void notifyMethod() {
        synchronized (lock) {
            System.out.println("begin notify ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
            lock.notify();
            System.out.println("end notify ThreadName = " + Thread.currentThread().getName() + " time = " + System.currentTimeMillis());
        }
    }

    public static void main(String[] args) throws InterruptedException {
        MyThread11 m11 = new MyThread11();
        for (int i = 0; i < 10; i++) {
            Thread11A ta = new Thread11A(m11);
            ta.start();
            Thread.sleep(50); //确保按序执行wait
        }
        Thread.sleep(1000);
        //唤醒5个
        for (int i = 0; i < 5; i++) {
            Thread11B tb = new Thread11B(m11);
            tb.start();
//            Thread.sleep(500);
        }
    }
}

class Thread11A extends Thread{
    private MyThread11 m11;

    public Thread11A(MyThread11 m11) {
        this.m11 = m11;
    }

    @Override
    public void run() {
        m11.waitMethod();
    }
}

class Thread11B extends Thread{
    private MyThread11 m11;

    public Thread11B(MyThread11 m11) {
        this.m11 = m11;
    }

    @Override
    public void run() {
        m11.notifyMethod();
    }
}
